#ifndef String_h
#define String_h

namespace TL {
    class String {
    protected:
        int m_Capacity;
        int m_Size;
        char *m_Text;
        char m_Undefined;

    protected:
        String(int capacity, int size, char *text);

    public:
        static short int strcmp(const char *str1, const char *str2);
        static void strcat(char *dest, const char *src);
        static void strcpy(char *dest, const char *src);
        static int strlen(const char *str);

    public:
        String();
        String(int capacity);
        String(const char *str);
        String(const String &str);
        ~String();

        char &At(int index);
        const char &At(int index) const;
        int Capacity() const;
        int FindFirstSubstring(const char *substr, int offset = 0);
        int FindFirstSubstring(const String &substr, int offset = 0);
        int FindFirstSubstringEnd(const char *substr, int offset = 0);
        int FindFirstSubstringEnd(const String &substr, int offset = 0);
        const char *GetCharString() const;
        String GetSubstring(int length, int offset = 0);
        void Insert(const char *str, int offset);
        void Insert(const String &str, int offset);
        bool IsEmpty() const;
        int Remove(const char *substr, int offset = 0);
        int Remove(const String &substr, int offset = 0);
        void RemoveSome(const char *parts, int offset = 0);
        void RemoveSome(const String &parts, int offset = 0);
        void RemoveSomeExcept(const char *exceptions, int offset = 0);
        void RemoveSomeExcept(const String &exceptions, int offset = 0);
        int Replace(const char *target_text, const char *replace_text, int offset = 0);
        int Replace(const char *target_text, const String &replace_text, int offset = 0);
        int Replace(const String &target_text, const char *replace_text, int offset = 0);
        int Replace(const String &target_text, const String &replace_text, int offset = 0);
        int Size() const;

        friend bool operator==(const char *str1, const String &str2);
        friend bool operator==(const String &str1, const char *str2);
        friend bool operator==(const String &str1, const String &str2);
        friend bool operator!=(const char *str1, const String &str2);
        friend bool operator!=(const String &str1, const char *str2);
        friend bool operator!=(const String &str1, const String &str2);
        String &operator=(const char *str);
        String &operator=(const String &str);
        friend String operator+(const char *str1, const String &str2);
        friend String operator+(const String &str1, const char *str2);
        friend String operator+(const String &str1, const String &str2);
        String &operator+=(const char *str);
        String &operator+=(const String &str);
        char &operator[](int index);
        const char &operator[](int index) const;
    };
}

#endif
